/*
    Marv the Miner for Nokia Series 30, 40 and 60 and for selected MIDP 1.0 supported phones
    Copyright (C) 2003-2004  Digital Entertainment Europe AS (http://www.digiment.no)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
	
    If you have any questions, please contact support@digiment.no
*/
import javax.microedition.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;
import java.util.*;
//import com.nokia.mid.ui.*;

public class Main extends com.nokia.mid.ui.FullCanvas implements Runnable
//public class Main extends Canvas implements Runnable
{
    boolean isLogo2 = false;

    static int LOGO_TIME = 2000;

    static final int C_P = 0;	// platform
    static final int C_S = 1;	// stair
    static final int C_M = 2;	// moving platform

    static final int C_Sucker = 3;	
    static final int C_Slope = 4;	
    static final int C_Press = 5;	
    static final int C_Lift = 6;	
    static final int C_Wall = 7;	

    static final int C_Trap = 11;	
    static final int C_Teleport = 12;	

    static final int C_Alien = 13; 
    static final int C_Bonus = 14; 
    static final int C_Static = 15; 
    static final int C_Man = 16; 

   	static final int C_S2 = 50;	// stair upper edges
   	static final int C_Sl2 = 51;	// slope upper edges

    static int fxp[] = {2, 4, 6, 8, 10,12,14,16,18,20,22,24,26,28,30};
	static int fyp[] = {3, 6, 9, 11,13,15,16,17,16,15,13,11,9, 6, 3};

    static Miner midlet;
    Display display;
    Thread mainThread;

    static int step = 4;              // animation step in pixels

    static Hashtable hp = null;
    static Hashtable hi = null;

    static Frame fPanel0 = null;
    static Frame fPanel1 = null;
    static Frame fPanel2 = null;
    static Frame fLogo = null;
    static Frame fLogo2 = null;
    static Frame fHead = null;

    static Frame fB[] = null;
    static Frame fS[] = null;
    static Frame fM[] = null;
    static Frame fW[] = null;
    static Frame fSu[] = null;
    static Frame fSl[] = null;
    static Frame fPr[] = null;
    static Frame fTr[] = null;
    static Frame fLi[] = null;

    static Frame frm = null;

    /////////////////////////////////////////////////////
    static Image img[] = null;
    static String img_names[] = null;

    static int logo_index;
    static int intro_index;
    static int intro2_index;
    static int abc_index;
    static int back_index;

   	static int img_index;

	static int[] abcw = {8,5,8,8,7,8,8,7,8,8,8,7,8,8,7,7,8,8,4,8,8,7,10,8,8,7,8,8,7,8,8,8,10,8,8,7,7,4,4,6,4,9,9,4,4};
	static int[] abcx = new int[abcw.length];

    Dynamic dyn[] = null;

    Dynamic cur = null;
    static Dynamic man = null;
    Dynamic fire = null;

    static Hashtable hAnims = null;
    int image_index = 0;

    static String str,str2;
  	static int panel_x,panel_dx,panel_width,panel_height,panel_y,panel_dy;
  	static CObject aObj[] = null;
  	static CObject obj = null, obj2 = null;

  	static Vector vM = null;
  	M msg = null;

    static int a_w = -1;					// size of map in pixels
    static int a_h = -1;

    static int a_x_d = 0;					// displacement in map
    static int a_y_d = 0;

    static int t_x_d = 0;					// temporary displacement in map
    static int t_y_d = 0;

    static int disp_x_range= 0;				// displacement changing interval
    static int disp_y_range= 0;

    static int s_w = 0;					// physical screen size
    static int s_h = 0;

    int c_lvl = 0,c_st,c_dyn;

    static int i,j,k,x,y,x1,y1,x2,y2,xm,ym,i2,j2,w1,h1,w2,h2,len,dx,dy,p_num,num;
	int type;
	int subtype;

  	int x_bound,y_bound;                    // bounds
   	int rel_dx = 0;							// relative man position
  	int rel_dy = 0;					       //

  	int platform_count = 0;

  	static Vector v1,v2,v;

  	int scores = 0;
  	int lifes = 0;
  	static int closed_blocks,start_closed_blocks,delay;
  	boolean flag,running;
    static int action = -15;
    static int actionMask = 0;

    int damaged = 0;

  	static Random rand = null;

  	static long startTime,leaveTime,prevTime;
  	long levelTime,currentTime,bonusTime;
	long panelTime = 0;

  	static int state;

  	static int lifeDelay = 0;

    long hh,mm,ss;

	static char[] buf = null;

	static boolean initOK = false;
	boolean ld = false;

    Dynamic dBonus = null;
    boolean isBonus = false;

    static Image ioff = null;
    static Graphics g = null;
    static Graphics gd = null;
    static Graphics goff = null;

    static String nextLevel = null;

    static Vector vMenu = null;
    static Vector vState = null;
    static int menuIndex = 0;
    static String menuName = "";
	static int menuDisp,menuRange,menuHeight,menuTop;
    static boolean isPointer = true;
    static boolean isState = true;
    static boolean menuLast = false;

    static char editText[] = null;
    static String letters = "abcdefghijklmnopqrstuvwxyz._";
    static int editX, editY;

	static int maxLevel = 0;
	static String names[] = null;

	static DataInputStream in = null,in2 = null;
	char ch;

	int memorySize = 0;
	static int vibra_delay = 0;
	static int dumpTime = 0;

	Main(){}

	static void out(String str)
	{
		if (midlet.cheats) System.out.println(str);
	}
    static int vendor = 0;

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	// network code - starts here
	static int securityCode = 110000;
	static int place = -1;		// place a player has taken
	// ******* NETWORK CODE REMOVED *******
	// ******* NETWORK CODE REMOVED *******
	// ******* NETWORK CODE REMOVED *******
	// network code - ends here
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	static int sendScore(String player,int score)
	{
		return place;
	}

    static void initStaticData()
    {
    	try
    	{
    		j = 0;
    		for (int i = 0; i < abcw.length; i++)
    		{
    			abcx[i] = j;
    			j += abcw[i];
    		}
   			buf = new char[100]; // char buffer

        	fB = new Frame[120];
        	fS = new Frame[12];
        	fM = new Frame[6];

        	fW = new Frame[6];
        	fSu = new Frame[6];
        	fSl = new Frame[7];
        	fPr = new Frame[6];
        	fTr = new Frame[4];
        	fLi = new Frame[4];

    		for (i = 0; i < fB.length; i++) fB[i] = null;
    		for (i = 0; i < fS.length; i++) fS[i] = null;
    		for (i = 0; i < fM.length; i++) fM[i] = null;
    		for (i = 0; i < fW.length; i++) fW[i] = null;
    		for (i = 0; i < fSu.length; i++) fSu[i] = null;
    		for (i = 0; i < fSl.length; i++) fSl[i] = null;
    		for (i = 0; i < fPr.length; i++) fPr[i] = null;
    		for (i = 0; i < fTr.length; i++) fTr[i] = null;
    		for (i = 0; i < fLi.length; i++) fLi[i] = null;

    		img = new Image[55];
    		img_names = new String[img.length];
    		for (i = 0; i < img.length; i++)
    		{
    			img[i] = null;
    			img_names[i] = null;
			}
    		logo_index = img.length - 1;
    		intro_index = img.length - 2;
    		intro2_index = img.length - 3;
    		back_index = img.length - 4;
    		abc_index = img.length - 5;

			pk_offset = new int[img.length];
			pk_size = new int[img.length];
			pk_index = new int[img.length];

			filename = new byte[10];
		   	editText = new char[3];

    		for (i = 0; i < 100; i++) 
    			if (gp("n"+i) != null) maxLevel = i;
    		names = new String[40];
    		for (i = 0; i < names.length; i++) names[i] = gp("n" + i);
    		hp = null;
    		System.gc();
   			vM = new Vector();
    		state = 100;
    	}
    	catch(Exception ex){}
    	vendor = 0;
    	try
    	{
    		// Nokia
    		Class.forName("com.nokia.mid.sound.Sound");
			vendor = 1;
    		try
    		{
    			Class.forName("com.nokia.mid.ui.DeviceControl");
				com.nokia.mid.ui.DeviceControl.setLights(0,100);
				vendor = 2;
			}
			catch(Exception ex2){}
		}
		catch(Exception ex){}

    	try
    	{
    		// Vodafone
    		Class.forName("com.vodafone.v10.system.device.DeviceControl");
			com.vodafone.v10.system.device.DeviceControl.getDefaultDeviceControl().setDeviceActive(com.vodafone.v10.system.device.DeviceControl.BACK_LIGHT,true);
			vendor = 3;
		}
		catch(Exception ex){}

    	try
    	{
    		// Motorola
    		Class.forName("com.motorola.multimedia.Vibrator");
    		Class.forName("com.motorola.multimedia.Lighting");
    		com.motorola.multimedia.Lighting.backlightOn();
			vendor = 4;
		}
		catch(Exception ex){}
    }


    static void beep(int code)
    {
		// Nokia 3650, 7650
		if (vendor == 1)
		try
		{
			if (midlet.muteSound == 0)
			{
				com.nokia.mid.sound.Sound sound = new com.nokia.mid.sound.Sound(1000,100);
				sound.play(1);
			}
		}
		catch(Exception ex){}

		// All other Nokias
		if (vendor == 2)
		try
		{
			if (midlet.muteSound == 0)
			{
				com.nokia.mid.sound.Sound sound = new com.nokia.mid.sound.Sound(1000,100);
				sound.play(1);
			}
			if (midlet.useVibra == 1)
			{
				com.nokia.mid.ui.DeviceControl.startVibra(50,500);
			}
		}
		catch(Exception ex){}

		// Vodafone SDK
		if (vendor == 3)
		try
		{
			if (midlet.useVibra == 1)
			{
				com.vodafone.v10.system.device.DeviceControl.getDefaultDeviceControl().setDeviceActive(com.vodafone.v10.system.device.DeviceControl.VIBRATION,true);
				vibra_delay = 10;
			}
		}
		catch(Exception ex){}

		// Motorola 7.5 
		if (vendor == 4)
		try
		{
			if (midlet.useVibra == 1)
			{
				com.motorola.multimedia.Vibrator.setVibrateTone(com.motorola.multimedia.Vibrator.VIBRATE_LONG);
				com.motorola.multimedia.Vibrator.vibrateFor(500);
			}
		}
		catch(Exception ex){}
    }

    static int rnd(int interval)
    {
    	return (rand.nextInt() & 0x07FFFFFFF) % interval;
    }

    void init(Display d, int level)
    {
        this.display = display;
        c_lvl = level;
		a_w = s_w = getWidth();
		a_h = s_h = getHeight();
		lifes = 3;

        init();
    }

    void release()
    {
    	initOK = false;
    	g = null;                
    	gd = null;
    	goff = null;
    	ioff = null;
    	if (hp != null) hp.clear();
    	hp = null;
    	vMenu = null;
    	vState = null;
		for (i = 0; i < fB.length; i++) fB[i] = null;
   		for (i = 0; i < fS.length; i++) fS[i] = null;
   		for (i = 0; i < fM.length; i++) fM[i] = null;
   		for (i = 0; i < fW.length; i++) fW[i] = null;
   		for (i = 0; i < fSu.length; i++) fSu[i] = null;
   		for (i = 0; i < fSl.length; i++) fSl[i] = null;
   		for (i = 0; i < fPr.length; i++) fPr[i] = null;
   		for (i = 0; i < fTr.length; i++) fTr[i] = null;
   		for (i = 0; i < fLi.length; i++) fLi[i] = null;
    	frm = null;
		fPanel0 = null;
		fPanel1 = null;
		fPanel2 = null;
		fLogo = null;
		fLogo2 = null;
		fHead = null;
   		for (i = 0; i < img.length; i++)
   		if (i != abc_index)
   		{
   			img[i] = null;
   			img_names[i] = null;
		}
		dBonus = null;
      	aObj = null;
      	dyn = null;

      	cur = null;
      	man = null;
      	fire = null;
      	obj = null;
      	obj2 = null;
      	msg = null;
      	v1 = null;
      	v2 = null;
      	v = null;
      	hAnims = null;
      	hi = null;
      	str = null;
      	str2 = null;
      	rand = null;
      	in = null;
      	in2 = null;
      	state = 0;
		System.gc();
    }

    void initMenu(String name,boolean isPointer,boolean isState) 
    {
    	state = 70;
		menuIndex = menuDisp = 0;
		menuTop = 20;
		menuHeight = 16;
		menuRange = (s_h - menuTop + (menuHeight >> 1)) / menuHeight;
		menuName = name;
		this.isPointer = isPointer;
		this.isState = isState;
		vMenu = new Vector();
		if (isState) vState = new Vector();
    	w1 = 0;
    	if (enqueue_abc()) loadImages();
    	initOK = true;
    }

    void initEditor(String name) 
    {
    	menuName = name;
    	editText[0] = 'a';
    	editText[1] = 'a';
    	editText[2] = 'a';
    	editX = 0;
    	editY = 0;
    	menuDisp = 0;
    	state = 80;
    	if (enqueue_abc()) loadImages();
    	initOK = true;
    }

    void initPlaceScreen()
    {
		state = 60;
		LOGO_TIME = 2000;
		initOK = true;
    }


    boolean enqueue_abc()
    {
    	if (img[abc_index] == null)
    	{
	    	img_names[abc_index] = "abc.png";
	    	return true;
		}
		return false;
    }

    boolean getState(int index)
    {
    	return ((Boolean)vState.elementAt(index)).booleanValue();
    }

    static Frame gf(String name)
    {
    	try
    	{
	    	str = gp(name);
   		 	if (str != null)
	   	 	{
		    	v = parse(str);
		    	img_index = ((Integer)v.elementAt(0)).intValue();
  			    str = gp("i" + img_index);

  			    if (str != null)
  			    {
  			    	if (img_names[img_index] == null)
  			    	{
  			    		img_names[img_index] = str + ".png";
  			    	}
			    	w1 = w2 = ((Integer)v.elementAt(3)).intValue();
		   		 	h1 = h2 = ((Integer)v.elementAt(4)).intValue();

		    		if (v.size() > 5) w2 = ((Integer)v.elementAt(5)).intValue();
			    	if (v.size() > 6) h2 = ((Integer)v.elementAt(6)).intValue();

		    		frm = new Frame(img_index,((Integer)v.elementAt(1)).intValue(),((Integer)v.elementAt(2)).intValue(),w1,h1,w2,h2);
	  				return frm;
				}
			}
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
		return null;
    }


    void init()
    {
    	initOK = false;
    	isBonus = false;
		try
		{
			if (state == 100)
			{
				LOGO_TIME = 2000;
	    		img_names[intro_index] = "in" + (s_w <= 96 ? 1 : 2) + ".png";
	    		if (isLogo2) img_names[intro2_index] = "moj.png";
	    		loadImages();

				if (img[intro2_index] != null)
				{
					w1 = img[intro2_index].getWidth();
					h1 = img[intro2_index].getHeight();
					fLogo2 = new Frame(intro2_index,0,0,w1,h1,w1,h1);
				}
				if (img[intro_index] != null)
				{
					w1 = img[intro_index].getWidth();
					h1 = img[intro_index].getHeight();
					fLogo = new Frame(intro_index,0,0,w1,h1,w1,h1);
				}
			}
			else
			if (state == 99)
			{
				LOGO_TIME = 2000;
	    		img_names[logo_index] = "logo.png";
	    		loadImages();
				if (img[logo_index] != null)
				{
					w1 = img[logo_index].getWidth();
					h1 = img[logo_index].getHeight();
					fLogo = new Frame(logo_index,0,0,w1,h1,w1,h1);
				}
		    	if (enqueue_abc()) loadImages();
			}
			else
			if (state == 98)
			{
				LOGO_TIME = 5;
				if (enqueue_abc()) loadImages();
			}
			else
			if (state == 101)
			{
				LOGO_TIME = 50;
			}
			else
			{
				ld = true;
		    	out("** " + c_lvl);
    			release();
            	rand = new Random(System.currentTimeMillis());
            	dumpTime = 100;

		    	nextLevel = gp("n" + (c_lvl + 1));

            	hAnims = new Hashtable();
            	hi = new Hashtable();

    		    man = null;
    		   	platform_count = 0;
//                System.gc();
            	// loading animations
            	readAnimation("an_m");
            	readAnimation("an_fire");
            	readAnimation("an_fb");
                System.gc();
            	for (i = 0; i < 10; i++) readAnimation("an_al" + i);
            	for (i = 0; i < 21; i++) readAnimation("an_bo" + i);
            	for (i = 0; i < 10; i++) readAnimation("an_st" + i);
            	for (i = 0; i < 10; i++) readAnimation("an_tr" + i);
                System.gc();
		    	obj2 = null;
            	try
            	{
					c_st = c_dyn = 0;
            	    for (i2 = 0; i2 < 2; i2++)
            	    {
		            	in = new DataInputStream(midlet.getClass().getResourceAsStream("/Res/l.map"));
		            	for (k = 0; k < c_lvl; k++)
   			         	{
   	    		     		len = in.readShort();
            				in.skip(len);
            			}
						len = in.readShort() - 4;
						len -= 4;
           				a_w = in.readShort();
           				a_h = in.readShort();
           				if (a_w > 220) a_w = 220;
           				if (a_h > 220) a_h = 220;

            	    	if (i2 != 0)
            	    	{
			            	aObj = new CObject[c_st];
			            	dyn = new Dynamic[c_dyn];
			            	c_st = c_dyn = 0;
			            }
            			for (k = 0; k < len;)
            			{
            				obj = null;
            				type = in.read();
            				subtype = in.read();
        	    			switch (type)
    	        			{
	            			case C_P:
    	    					x1 = in.readShort();
	        					y1 = in.readShort();
            					x2 = in.readShort();
            					y2 = in.readShort();
            					k += 10;
        	    				if (x1 != x2)
    	       	 				{
	            					if (i2 == 0) c_st++;
    	        					else
    	        					{
		    	   	     				platform_count++;
   	        	 						if (fB[subtype * 6] == null)
   	        	 							for (i = 0, j = subtype * 6; i < 6; i++, j++) fB[j] = gf("b" + j);
		    		        			obj = new CObject(type,subtype,x1,y1,x2,y2);
   		 			        			obj.init();
			        	    			aObj[c_st++] = obj;
			        	    		}
        	    				}
            					break;	
	            			case C_S:
    	    					x1 = x2 = in.readShort();
	        					y1 = in.readShort();
            					y2 = in.readShort();
            					k += 8;
            					if (i2 == 0) c_st++;
            					else
            					{
	            					if (fS[subtype << 1] == null) 
   		         					{
   	    	     						fS[subtype << 1] = gf("s" + subtype + ".0");
            							fS[subtype + subtype + 1] = gf("s" + subtype + ".1");
            						}
	            					obj = new CObject(type,subtype,x1,y1,x2,y2);
    	        					obj.init();
		        	    			aObj[c_st++] = obj;
        	    				}
            					break;	
            				case C_M:
    	    					x1 = in.readShort();
	        					y1 = in.readShort();
            					x2 = in.readShort();
            					y2 = in.readShort();
            					k += 10;
            					if (i2 == 0) c_st++;
            					else
            					{
	            					if (fM[subtype] == null) fM[subtype] = gf("mv" + subtype);
		            				obj = new CObject(type,subtype,x1,y1,x2,y2);
    		        				obj.init();
		        	    			aObj[c_st++] = obj;
        		    			}
            					break;
							case C_Sucker:
    	    					x1 = in.readShort();
	        					y1 = in.readShort();
            					x2 = in.readShort();
            					y2 = in.readShort();
            					k += 10;
            					if (i2 == 0) c_st++;
            					else
            					{
	        						if (fSu[subtype * 6] == null)
    	    							for (i = 0, j = subtype * 6; i < 6; i++, j++) fSu[j] = gf("su" + subtype + "." + j);
    		        				obj = new CObject(type,subtype,x1,y1,x2,y2);
		    	    				obj.init();
		        	    			aObj[c_st++] = obj;
        	    				}
            					break;
							case C_Slope:
    	    					x1 = in.readShort();
	        					y1 = in.readShort();
            					x2 = in.readShort();
            					y2 = in.readShort();
            					k += 10;
            					if (i2 == 0) c_st++;
            					else
            					{
    	    						if (fSl[subtype * 7] == null)
	    	   							for (i = 0, j = subtype * 7; i < 7; i++, j++) fSl[j] = gf("sl" + subtype + "." + j);
    	    	    				obj = new CObject(type,subtype,x1,y1,x2,y2);
		        					obj.init();
		        	    			aObj[c_st++] = obj;
        	    				}
      	     					break;
							case C_Press:
    	    					x1 = x2 = in.readShort();
	        					y1 = in.readShort();
            					y2 = in.readShort();
            					k += 8;
            					if (i2 == 0) c_st++;
            					else
            					{
	            					if (fPr[subtype << 1] == null) 
    	        					{
        	    						fPr[subtype << 1] = gf("pr" + subtype + ".0");
            							fPr[subtype + subtype + 1] = gf("pr" + subtype + ".1");
            						}
	            					obj = new CObject(type,subtype,x1,y1,x2,y2);
	            					obj.fw = fPr[subtype << 1].w;
	            					obj.fh = fPr[subtype << 1].h;
    	        					obj.init();
		        	    			aObj[c_st++] = obj;
	        	    			}
            					break;	
							case C_Lift:
    	    					x1 = x2 = in.readShort();
	        					y1 = in.readShort();
            					y2 = in.readShort();
            					k += 8;
            					if (i2 == 0) c_st++;
            					else
            					{
	            					if (fLi[subtype << 1] == null) 
    	        					{
        	    						fLi[subtype << 1] = gf("li" + subtype + ".0");
            							fLi[subtype + subtype + 1] = gf("li" + subtype + ".1");
            						}
	            					obj = new CObject(type,subtype,x1,y1,x2,y2);
	            					obj.fw = fLi[subtype << 1].w;
	            					obj.fh = fLi[subtype << 1].h;
    	        					obj.init();
		        	    			aObj[c_st++] = obj;
        	    				}
            					break;	
							case C_Wall:
    	    					x1 = x2 = in.readShort();
	        					y1 = in.readShort();
            					y2 = in.readShort();
            					k += 8;
            					if (i2 == 0) c_st++;
            					else
            					{
	            					if (fW[subtype << 1] == null) 
    	        					{
        	    						fW[subtype << 1] = gf("w" + subtype + ".0");
            							fW[subtype + subtype + 1] = gf("w" + subtype + ".1");
            						}
	            					obj = new CObject(type,subtype,x1,y1,x2,y2);
    	        					obj.init();
		        	    			aObj[c_st++] = obj;
        	    				}
            					break;	
							case C_Teleport:
            					if (i2 == 0) c_st++;
            					else
            					{
	    	    					x1 = in.readShort();
		        					y1 = in.readShort();
        	    					k += 6;
	        						if (fTr[subtype + subtype] == null)
	        						{
            							fTr[subtype + subtype] = gf("te" + subtype + ".0");
            							fTr[subtype + subtype + 1] = gf("te" + subtype + ".1");
	        						}
	            					obj = new CObject(type,subtype,x1,y1,x1,y1);
	    	        				obj.init();
		        	    			aObj[c_st++] = obj;
	    	    					if (obj2 == null) obj2 = obj;
	    	    				}
            					break;
            				case C_Trap:
	        					x1 = in.readShort();
		       					y1 = in.readShort();
           						k += 6;
	      	   					if (i2 == 0) c_dyn++;
	           					else
            					{
	    	    					cur = new Dynamic(Dynamic.T_T,subtype,x1,y1,null,gf("tr" + subtype),"an_tr" + subtype);
	        						cur.delay_range = Integer.parseInt(gp("trd" + subtype));
		        	    			dyn[c_dyn++] = cur;
            					}
            					break;	
            				case C_Alien:
    	    					x1 = in.readShort();
	        					y1 = in.readShort();
            					k += 6;
	      	   					if (i2 == 0) c_dyn++;
	           					else
            					{
	            					dyn[c_dyn++] = new Dynamic(Dynamic.T_A,subtype,x1,y1,null,gf("a" + subtype),"an_al" + subtype);
	            				}
            					break;	
            				case C_Bonus:
    	    					x1 = in.readShort();
	        					y1 = in.readShort();
            					k += 6;
	      	   					if (i2 == 0) c_dyn++;
	           					else
            					{
	            					dyn[c_dyn++] = new Dynamic(Dynamic.T_B,subtype,x1,y1,null,gf("bo" + subtype),"an_bo" + subtype);
    	        					if ((subtype == 2) && (dBonus == null))
        	    					{
            							dBonus = new Dynamic(Dynamic.T_B,0,0,0,null,gf("fb"),"an_fb");
            						}
            					}
            					break;	
            				case C_Static:
    	    					x1 = in.readShort();
	        					y1 = in.readShort();
            					k += 6;
	      	   					if (i2 == 0) c_dyn++;
	           					else
            					{
									dyn[c_dyn++] = new Dynamic(Dynamic.T_D,subtype,x1,y1,null,gf("st" + subtype),"an_st" + subtype);
	            				}
            					break;	
            				case C_Man:
    	    					x1 = in.readShort();
	        					y1 = in.readShort();
            					k += 6;
	      	   					if (i2 != 0)
            					{
	            					man = new Dynamic(Dynamic.T_M,0,x1,y1,null,gf("man"),"an_m");
	            				}
            					break;	
            				default:
   	    	     				break;	
   		         			}
	            		}
		            	in = null;
		            	System.gc();
            		}
            	}
            	catch(Exception ioex){ioex.printStackTrace();}
            	System.gc();
       			fire = new Dynamic(Dynamic.T_D,0,0,0,null,gf("fire"),"an_fire");
       			fire.visible = false;
				hAnims.clear();
				hAnims = null;

				hi.clear();
				hi = null;
            	System.gc();

            	panel_x = panel_dx = 0;
            	// from vector to array...
            	for (i = aObj.length - 1; i >= 0; i--)
            	{
            		obj = aObj[i];
            		if (obj.type == C_Teleport)	
            		{
            			obj.nextObj = obj2;		// remember next step object
            			obj2 = obj;
            		}
            	}
            	fHead = gf("head");
            	fPanel0 = gf("panel0");
            	fPanel1 = gf("panel1");
            	fPanel2 = gf("panel2");
            	panel_width = s_w;
            	panel_height = fPanel0.fh;

				if (hp != null) hp.clear();
		    	hp = null;
				System.gc();
				///////////////////////////////////////////////////////////////////////////////////

    			disp_x_range = a_w - s_w;
    			disp_y_range = a_h - s_h;

    			if (disp_x_range < 0) disp_x_range /= 2;
    			if (disp_y_range < 0) disp_y_range = 0;

              	x_bound = s_w / 2;
              	y_bound = s_h / 2;

              	locateMan();

            	levelTime = 300;
            	leaveTime = -1;

            	if (midlet.cheats) lifes = 3;
            	start_closed_blocks = 0;
            	damaged = 0;


            	enqueue_abc();
				img_names[back_index] = "bg.png";
				loadImages();

				System.gc();
				createBuffer();
			}

   			p_num = -1;
   			start_closed_blocks = 0;

			if (state == 0)
   			{
		    	num = 0;
		    	h1 = s_h - a_h;
		    	if (h1 < 0) h1 = 0;
				drawType(C_Wall);

				drawType(C_Slope);
				drawType(C_Sucker);
				drawType(C_Teleport);
				drawType(C_S);
				drawType(C_P);
				drawType(C_Sl2);
				drawType(C_S2);

				for (i = 0; i < fB.length; i += 6)
				{
					if (fB[i + 3] != null) img[fB[i + 3].index] = null;
					if (fB[i + 4] != null) img[fB[i + 4].index] = null;
					if (fB[i + 5] != null) img[fB[i + 5].index] = null;
					fB[i + 3] = null;
					fB[i + 4] = null;
					fB[i + 5] = null;
				}
   				for (i = 0; i < fW.length; i++)
				{
					if (fW[i] != null) img[fW[i].index] = null;
					fW[i] = null;
				}
				for (i = 0; i < fSu.length; i++)
				{
					if (fSu[i] != null) img[fSu[i].index] = null;
					fSu[i] = null;
				}
				vM.removeAllElements();
				closed_blocks = start_closed_blocks;
	        	startTime = System.currentTimeMillis();
			}
			System.gc();

			initOK = running = true;
			action = -15;
			lifeDelay = 20;
        	tsum = tcnt = 0;
        	panel_y = panel_dy = 0;

        	memorySize = (int)(Runtime.getRuntime().freeMemory());

			out("After: " + memorySize);
		}
		catch(Exception ex)
        {
        	ex.printStackTrace();
        }
    }

    static void createBuffer()
    {

   		out("SB1=" + Runtime.getRuntime().freeMemory());
   		h1 = a_h > s_h ? a_h : s_h;

		ioff = Image.createImage(a_w,h1);
		goff = ioff.getGraphics();

		if (img[back_index] != null)
   		for (i = 0; i < a_w; i += 32)
    		for (j = 0; j < h1; j += 32)
  				goff.drawImage(img[back_index],i,j,20);
		else
		{
   			goff.setColor(0x000000);
   			goff.fillRect(0,0,a_w,h1);
   		}
   		img[back_index] = null;
		System.gc();
   		out("SB2=" + Runtime.getRuntime().freeMemory());
   	}

    static void locateMan()
    {
      	// setting display position to miner
      	a_x_d = man.x - (s_w >> 1);
      	a_y_d = man.y - (s_h >> 1);
    	if (a_x_d < 0) a_x_d = 0;
    	if (a_y_d < 0) a_y_d = 0;
    	if (a_x_d >= disp_x_range) a_x_d = disp_x_range;
    	if (a_y_d >= disp_y_range) a_y_d = disp_y_range;
    }

    static void drawP()
    {
    	gd = goff;
		h1 = s_h - a_h;
		if (h1 < 0) h1 = 0;
   		for (j = obj.x1, x = obj.x1, y = obj.y1 + obj.disp + h1, k = 0;
   			 j < obj.x2;
				 j += 10, x += 10, y += obj.k, k++)
		{
			if (obj.blocks[k]) 
				frm = fB[obj.imageIndex];
			else
			{             
				if (p_num == -1) start_closed_blocks++;
				frm = fB[obj.imageIndex + 3];
			}
   			if (frm != null)
   			{
   				if ((p_num == k) || (p_num == -1)) frm.draw(x,y,obj.x1,0,obj.x2 - obj.x1 + 4,a_h + h1);
   				if (p_num == k)
   				{
					for (i2 = 0; i2 < aObj.length; i2++)
					{
						obj2 = aObj[i2];
						if (obj2.type == C_S)
							if ((obj2.x1 - 12 <= x) && (obj2.x1 + 10 >= x) && (obj.ymin - 10 <= obj2.ymin) && (obj.ymax + 10 >= obj2.ymin))
								drawS2();
					}
				}
   			}
   		}
   		if (p_num != -1) drawType(C_Sl2);
    }

    static void drawS2()
    {
    	gd = goff;
		h1 = s_h - a_h;
		if (h1 < 0) h1 = 0;
		frm = fS[(obj2.subtype << 1) + 1];
		if (frm != null)
		{
    		dy = frm.h;
			x = obj2.x1 - (frm.w >> 1);
			for (y1 = 0, y = obj2.ymin + h1; y1 < 12; y += dy, y1 += dy) 
				frm.draw(x,y,0,obj2.ymin + h1,a_w,obj2.ymax - obj2.ymin);
		}
    }

    static void drawType(int c_t)
    {
    	gd = goff;
		h1 = s_h - a_h;
		if (h1 < 0) h1 = 0;
		for (i = 0; i < aObj.length; i++)
		{
			try
			{
				obj = obj2 = aObj[i];
				if ((c_t == C_P) && (obj.type == C_P)) drawP();
				else
				if ((c_t == C_S) && (obj.type == C_S))
				{
		    		frm = fS[obj.subtype << 1];
		    		if (frm != null)
		    		{
			    		dy = frm.h;
		    			x = obj.x1 - (frm.w >> 1);
						for (y1 = obj.ymin, y = obj.ymin + h1; y1 < obj.ymax; y += dy, y1 += dy) 
							frm.draw(x,y,0,obj.ymin + h1 + 2,a_w,obj.ymax - obj.ymin);
					}
				}
				else
				if ((c_t == C_S2) && (obj.type == C_S)) drawS2();
				else
				if ((c_t == C_Wall) && (obj.type == C_Wall))
				{
					dy = 0;
		    		frm = fW[obj.subtype << 1];
		    		if (frm != null)
		    		{
			    		dy = frm.h;
		    			x = obj.x1 - (frm.w >> 1);
						frm.draw(x,obj.ymin + h1,0,obj.ymin + h1,a_w,obj.ymax - obj.ymin);
					}
	    			frm = fW[(obj.subtype << 1) + 1];
	    			if (frm != null)
	    			{
	    				x = obj.x1 - (frm.w >> 1);
			    		dy = frm.h;
						for (y1 = obj.ymin, y = obj.ymin + h1; y1 < obj.ymax; y += dy, y1 += dy) 
							frm.draw(x,y,0,obj.ymin + dy + h1,a_w,obj.ymax - obj.ymin - dy);
					}
				}
				else
				if ((c_t == C_Sucker) && (obj.type == C_Sucker))
				{
					x1 = obj.x1;
					y1 = obj.y1;
					x2 = obj.x2;
					y2 = obj.y2;
					ym = obj.ymin - 20;
					dx = 0;
					frm = fSu[obj.subtype * 6];
					if (frm != null)
					{
						for (y = ym; y <= y1; y += frm.h) 
							frm.draw(x1 - (frm.w >> 1),y + h1,0,ym + h1,a_w,y1 - ym - 3);
						for (y = ym; y <= y2; y += frm.h) 
							frm.draw(x2 - (frm.w >> 1),y + h1,0,ym + h1,a_w,y2 - ym - 3);
					}
					frm = fSu[obj.subtype * 6 + 3];
					if (frm != null)
					{
						for (x = obj.xmin; x <= obj.xmax; x += frm.w) 
							frm.draw(x,ym - (frm.h >> 1) + h1,obj.xmin,0,obj.xmax - obj.xmin,a_h + h1);
					}
					frm = fSu[obj.subtype * 6 + 4];
					if (frm != null)
					{
						frm.draw(obj.xmin - (frm.w >> 1),ym - (frm.h >> 1) + h1,0,0,a_w,a_h + h1);
					}
					frm = fSu[obj.subtype * 6 + 2];
					if (frm != null)
					{
						frm.draw(obj.xmax - (frm.w >> 1),ym - (frm.h >> 1) + h1,0,0,a_w,a_h + h1);
					}
					frm = fSu[obj.subtype * 6 + 1];
					if (frm != null)
					{
						frm.draw(obj.x1 - (frm.w >> 1),y1 - frm.h + h1,0,0,a_w,a_h + h1);
					}
					frm = fSu[obj.subtype * 6 + 5];
					if (frm != null)
					{
						frm.draw(obj.x2 - (frm.w >> 1),y2 - frm.h + h1,0,0,a_w,a_h + h1);
					}
				}
				else
				if ((c_t == C_Slope) && (obj.type == C_Slope))
				{
					x1 = obj.x1 - 7 - (obj.k < 0 ? 13 : 0);
			    	frm = fSl[obj.subtype * 4 + obj.imageIndex];
			    	dx = obj.k * frm.h;
			    	if (frm != null)
			    	for (j = obj.y1, x = x1; j < obj.y2; j += frm.h, x += dx)
			    	{
						frm.draw(x,j + h1,0,obj.ymin + h1,a_h,obj.ymax - obj.ymin);
			    	}
				}
				else
				if ((c_t == C_Sl2) && (obj.type == C_Slope))
				{
					x1 = obj.x1 - 7 - (obj.k < 0 ? 13 : 0);
			    	frm = fSl[obj.subtype * 4 + obj.imageIndex + 3];
			    	dx = obj.k * frm.h;
			    	if (frm != null)
			    	for (j = obj.y1, x = x1; j < obj.y2; j += frm.h, x += dx)
			    	{
						frm.draw(x,j + h1,0,obj.ymin + h1,a_h,obj.ymax - obj.ymin);		    				
			    	}
			    	if (obj.k == 0) 
			    	{
			    		frm = fSl[obj.subtype * 4 + 6];
//						frm.draw(x1,obj.y1,0,obj.ymin + h1,a_h,obj2.ymax - obj.ymin);
			    	}
			    	else frm = fSl[obj.subtype * 4 + obj.imageIndex];
			    	if (frm != null)
			    	{
						frm.draw(x1,obj.y1 + h1,0,obj.ymin + h1,a_h,obj2.ymax - obj.ymin);		    				
			    	}
				}
				else
				if ((c_t == C_Teleport) && (obj.type == C_Teleport))
				{
					frm = fTr[obj.subtype << 1];
					if (frm != null)
					{
						x = obj.x1 - (frm.w >> 1);
						y = obj.y1 - (y1 = frm.h) + h1;
						frm.draw(x,y,x,y,frm.fw,frm.fh);
						frm = fTr[(obj.subtype << 1) + 1];
						if (frm != null)
						{
							x = obj.x1 - (frm.fw >> 1);
							y = obj.y1 - y1 + 1 + h1;
							goff.setClip(x,y,frm.fw,frm.fh);
							goff.drawImage(img[frm.index],x - frm.fw * (num++),y,20);
				    	}
			    	}
				}
			}
			catch(Exception ex)
			{
				ex.printStackTrace();
			}
		}
    }

    void readAnimation(String prefix)
    {
    	if (v1 == null) v1 = new Vector();
    	for (j = 0; j < 16; j++)
    		if ((str = gp(prefix + "." + j)) != null) v1.addElement(parse(str));
    	if (v1.size() > 0)
    	{
    		hAnims.put(prefix,v1);
    		v1 = null;
    	}
    }

   	static String tmp = null;
    static Vector parse(String str)
    {
    	tmp = "";
    	int l = str.length() - 1;
    	v2 = new Vector();
    	for (int i = 0; i <= l; i++)
    	{
    		char c = str.charAt(i);
    		if (i == l) tmp += c;
    		if ((c == ',') || (i == l))
    		{
    			try
    			{
    				v2.addElement(new Integer(Integer.parseInt(tmp)));
    			}
    			catch(Exception ex){}
    			tmp = "";
    		}
    		else tmp += c;
    	}
    	tmp = null;
    	return v2;
    }

    void addMessage(int x,int y,String text)
    {
    	msg = new M(x,y,text);
    	vM.addElement(msg);
    }

    static boolean isKeyPressed = false;
    protected void keyPressed(int keyCode)
    {
	    isKeyPressed = true;
	    action = keyCode;
	    switch (action)
	    {
            case -3:// left
			case Canvas.KEY_NUM4:
					actionMask = 1;
					break;
			case -4:// right
			case Canvas.KEY_NUM6:
					actionMask = 2;
					break;
			case -1:// up
			case Canvas.KEY_NUM2:
					actionMask = 4;
					break;
			case -2:// down
			case Canvas.KEY_NUM8:
					actionMask = 8;
					break;
			case -5:// jump
			case -6:
			case Canvas.KEY_NUM5:
					actionMask = 16;
					break;
			case Canvas.KEY_NUM1:// jump
					actionMask = 32;
					break;
			case Canvas.KEY_NUM3:// jump
					actionMask = 64;
					break;
			case Canvas.KEY_NUM7:break;
			case Canvas.KEY_NUM9:break;
			case -15:break;
			case -7:
			case Canvas.KEY_STAR:
					actionMask = 128;
					break;
			default:break;
		}
	}

    protected void keyReleased(int keyCode)
    {
		actionMask = 0;
		isKeyPressed = false;
	}

	void updateMsg()
	{
      	for (i = 0; i < vM.size(); i++)
      	{
      		msg = (M)vM.elementAt(i);
      		msg.update();
      		y = (a_h - s_h);
      		if (y > 0) y = 0;
      		if ((msg.x < 0) || (msg.y < y) || (msg.x > a_w) || (msg.y > a_h))
      		{
      			vM.removeElementAt(i);
      		}
      	}
	}                   	

    void update()
    {
		updateMsg();

		for (i = 0; i < aObj.length; i++) aObj[i].update();

		// if small by vertical

		if (s_h < 80)
		if ((System.currentTimeMillis() - panelTime > 3000) || (state != 0))
		{
			panel_dy = 1;
   			panelTime = System.currentTimeMillis();
		}

    	if (state == 0)
    	{
    		if (s_h < 80)
    		if (action != -15)
    		{
    			panel_dy = -1;
    			panelTime = System.currentTimeMillis();
    		}
    	    switch (action)
    	    {
                case -3:
    			case Canvas.KEY_NUM4:
    					man.shift(-step,0);
    					break;
				case -4:
    			case Canvas.KEY_NUM6:
    					man.shift(step,0);
    					break;
				case -1:
    			case Canvas.KEY_NUM2:
    					man.shift(0,-step);
    					break;
				case -2:
    			case Canvas.KEY_NUM8:
    					man.shift(0,step);
    					break;
				case -5:
				case -6:
    			case Canvas.KEY_NUM5:
    					man.jump(99);
    					break;
    			case Canvas.KEY_NUM1:
    					man.jump(-step);
    					break;
    			case Canvas.KEY_NUM3:
    					man.jump(step);
    					break;
				case Canvas.KEY_NUM7:break;
				case Canvas.KEY_NUM9:break;
    			case -15:break;
				case -7:
    			case Canvas.KEY_STAR:
    					action = -15;
    					leaveTime = System.currentTimeMillis();
    					if (lifes > 0) midlet.menuLevel = 10;
    					else 
    					{
    						midlet.menuLevel = 0;
    						midlet.paused = false;
						}
			    		midlet.returnMenu();
    					break;
    			default:break;
    		}
		}

		for (i = 0; i < dyn.length; i++)
		{
			cur = dyn[i];
			if (cur != null)
			if (cur.visible)
			{
    			dyn[i].update();
  				cur.alarm = false;					
				if (cur.class_type == Dynamic.T_B)
					if (cur.inUse)
					{
						if ((!man.inUse) || ((state > 0) && (state < 33))) 
						{
							dyn[i].visible = false;	
						}
					}
    			if (state == 0)
    			if ((cur.curObj == man.curObj) && (man.curObj != null))
    			{
    				if ((cur.x - man.x >= - 30) && (cur.x - man.x <= 30))
    				{
	    				cur.alarm = true;					
    				}

    				if ((cur.x - man.x >= - 10) && (cur.x - man.x <= 10))
    				{
    					if ((cur.class_type == Dynamic.T_A)  ||
    						((cur.class_type == Dynamic.T_T) && (cur.type == 0) && (cur.a2 != 1)))
    					{
   							if (!cur.inUse)
	   						{
    							if (lifes > 0 && (damaged == 0) && (!man.inUse || isBonus))
    							{
    								if (((cur.class_type == Dynamic.T_A) || (cur.class_type == Dynamic.T_T)) && isBonus)
    								{
	    								addMessage(man.x,man.y,"25");
    									scores += 25;
			    						dyn[i] = null;
    								}
    								else
    								{
    									state = 3;
    								}
								}

    							if ((man.inUse) && (!isBonus) && (cur.class_type == Dynamic.T_T) && (cur.type != 0)) state = 3;

    							if ((man.inUse) && (!isBonus) && ((cur.class_type == Dynamic.T_A) || 
    								((cur.class_type == Dynamic.T_T) && (cur.type == 0))))
  	 							{
									dyn[i] = null;
	    							man.inUse = false;
    								addMessage(man.x,man.y,"25");
   									scores += 25;
		    						fire.a2 = 1;
    								fire.x = man.x;
    								fire.y = man.y;
			    					fire.finished = false;
    								fire.visible = true;
	    							fire.loop = false;
    							}
							}
    					}
    					else
    					if ((cur.class_type == Dynamic.T_T) && (cur.type != 0) && (cur.a2 != 1))
    					{
    						if (lifes > 0 && (damaged == 0))
    						{
								state = 3;
							}
    					}
    					if (cur.class_type == Dynamic.T_B)
    					{
    						if (cur.type == 1) // bomb
    						{
    							if ((!cur.inUse) && (!man.inUse) && (!isBonus))
    							{
    								cur.inUse = true;
    								man.inUse = true;
    							}
    						}
    						else
    						if (cur.type == 2) // bonus mode
    						{
    							if ((!isBonus) && (!man.inUse))
    							{
    								isBonus = true;
   									cur.inUse = true;
   									man.inUse = true;
    								bonusTime = System.currentTimeMillis();
	    							blink = 0;
								}
    						}
    						else
    						{
    							if (cur.type == 0) // life
    							{
    								lifes++;
		   						}
    							else
    							{
    								num = 10;
									switch(cur.type)
									{
										case 3: num = 100; break;
										case 4: num = 50; break;
										case 5: num = 10; break;
										case 6: num = 20; break;
										default:;
									}
    								addMessage(man.x,man.y,num + "");
    								scores += num;
    							}
	    						dyn[i].visible = false;
    						}
    					}
    				}
    			}
			}
		}
		if (state != 5) man.update();
    	rel_dx = man.x - a_x_d;
    	rel_dy = man.y - a_y_d;

    	if ((rel_dx < x_bound) && (man.sdx < 0))
    	{
    		a_x_d += man.sdx;
    		if (a_x_d > 0) panel_dx = 4;

    	}
    	if ((rel_dx > (s_w - x_bound)) && (man.sdx > 0))
    	{
    		a_x_d += man.sdx;
    		if ((a_x_d < disp_x_range)) panel_dx = -4;
    	}

    	if ((rel_dy < (y_bound + panel_height)) && (man.sdy < 0))
    		a_y_d += man.sdy;
    	if ((rel_dy > (s_h - y_bound)) && (man.sdy > 0))
    		a_y_d += man.sdy;

    	if (a_x_d < 0) a_x_d = 0;
    	if (a_y_d < 0) a_y_d = 0;
    	if (a_x_d >= disp_x_range) a_x_d = disp_x_range;
    	if (a_y_d >= disp_y_range) a_y_d = disp_y_range;

    	// hiding panel
    	if (s_h < 80)
    	{
    		if (panel_dy < 0) panel_y += panel_dy;
    		else
	    	if (panel_dy > 0) panel_y += panel_dy;
    		if (panel_y >= 0)
    		{
	    		panel_y = panel_dy = 0;
    		}
    		if (panel_y < -12)
	    	{
    			panel_y = -12;
    			panel_dy = 0;
	    	}
    	}
        /*
   		panel_x += panel_dx;
   		if (panel_x < 0) panel_x = panel_dx = 0;
   		if ((panel_x + panel_width) > s_w)
   		{
   			panel_x = s_w - panel_width;
   			panel_dx = 0;
   		}
        */
    }

	long tt = 0, tt2 = 0, tsum = 0, tcnt = 0;
	void updateMenu()
	{
		if (vMenu != null)
		{
			try
			{
			    switch (action)
			    {
					// left
					case -3: // 7210
					case Canvas.KEY_NUM4:menuIndex -= menuRange;
							break;
					// right
					case -4: // 7210
					case Canvas.KEY_NUM6:menuIndex += menuRange;
							break;
					// up
					case -1: // 7210
					case Canvas.KEY_NUM2:
							if (isPointer) menuIndex --;
							else menuDisp -= menuRange;
							break;
					// down
					case -2: // 7210
					case Canvas.KEY_NUM8:
							if (isPointer) menuIndex ++;
							else menuDisp += menuRange;
							break;
					// select
					case -5: // 60
					case -6: // 7210
					case Canvas.KEY_NUM5:
							if (isState)
							{
								if (menuIndex + 1 < vMenu.size())
								{
									vState.setElementAt(new Boolean(!(((Boolean)vState.elementAt(menuIndex)).booleanValue())),menuIndex);
								}
								else
								{
									action = -15;
									if (isState) midlet.setupOk();
									else midlet.menuBack();
								}
							}
							else if (menuLast)
							{
								action = -15;
								midlet.menuBack();
							}
							else midlet.menuOk(menuIndex);
							break;
					case Canvas.KEY_NUM1:
					case Canvas.KEY_NUM3:
					case Canvas.KEY_NUM7:
					case Canvas.KEY_NUM9:break;
					case -15:break;

					default:break;

					// exit
					case -7: // 7210
//					case KEY_STAR:
							if (midlet.menuLevel != 0)
							{
								action = -15;
								if (isState) midlet.setupOk();
								else midlet.menuBack();
							}
							break;
				}

//				if (menuIndex < 0) menuIndex = vMenu.size() - 1;
//				if (menuIndex >= vMenu.size()) menuIndex = 0;
				if (menuIndex < 0) menuIndex = menuIndex = 0;
				if (menuIndex >= vMenu.size()) menuIndex = vMenu.size() - 1;

				if (isPointer)
				{
					if (menuIndex < menuDisp) menuDisp = menuIndex;
					if (menuDisp + menuRange <= menuIndex) menuDisp = menuIndex - menuRange + 1;
				}
				else
				{
					if (menuDisp + menuRange > vMenu.size()) menuDisp = vMenu.size() - menuRange;
					if (menuDisp < 0) menuDisp = 0;
				}
			}
			catch(Exception ex){}
		}
        action = -15;
	}

	void updateEditor()
	{
		try
		{
		    switch (action)
		    {
				case -3:
				case Canvas.KEY_NUM4:if (editX > 0) editX--;
						break;
				case -4:
				case Canvas.KEY_NUM6:if (editX < 6) editX++;
						break;
				case -1:							
				case Canvas.KEY_NUM2:if (editY > 0) editY--;
						break;
				case -2:
				case Canvas.KEY_NUM8:if (editY < 3) editY++;
						break;
				case -6:
				case -5:
				case Canvas.KEY_NUM5:
						if (letters.charAt(editY * 7 + editX) == '_')
						{
							if (menuDisp > 0) menuDisp--;
						}
						else
						{
							if (menuDisp >= 2)
							{
								midlet.editOk(new String(editText));
							}
							else
							{
								menuDisp++;
							}
						}
						break;
				case Canvas.KEY_NUM1:
				case Canvas.KEY_NUM3:
				case Canvas.KEY_NUM7:
				case Canvas.KEY_NUM9:break;
				case -15:break;
				default:break;
				case -7:
				case KEY_STAR:
						action = -15;
						midlet.editBack();
						break;
			}
			ch = letters.charAt(editY * 7 + editX);
			if (ch != '_')
			{
				if (ch == '.') ch = ' ';
				editText[menuDisp] = ch;
			}
		}
		catch(Exception ex){}
        action = -15;
	}

    static int si,sl,sx,sn;
    static char sc;

    static void drawString(String str,int x,int y)
    {
    	sl = str.length();
    	if (sl > buf.length) sl = buf.length;
    	for (si = 0; si < sl; si++)
    		buf[si] = str.charAt(si);
    	drawChars(0,sl,x,y);
    }

    static void calcSn()
    {
		sn = 0;
		if (sc == '^')
		{
			int d = (sx / 25) * 25;
			if (sx != d) d = d + 25;
			sx = d;
		}
		else
		if (sc == '&')
		{
			int d = (sx / 14) * 14;
			if (sx != d) d = d + 14;
			sx = d;
		}
		else
		if (sc == '%')
		{
			int d = (sx / 14) * 14;
			if (sx != d) d = d + 14;
			sx = d;
		}
		else
		if ((sc >= '0') && (sc <= '9'))
		{
			sn = (int)(sc - '0');
		}
		else
		if (sc == '#')
		{
			sn = 36;
		}
		else
		if (sc == '.')
		{
			sn = 37;
		}
		else
		if (sc == ':')
		{
			sn = 38;
		}
		else
		if (sc == '_')
		{
			sn = 39;
		}
		else
		if (sc == ',')
		{
			sn = 40;
		}
		else
		if (sc == '*')
		{
			sn = 41;
		}
		else
		if (sc == '@')
		{
			sn = 42;
		}
		else
		if (sc == '(')
		{
			sn = 43;
		}
		else
		if (sc == ')')
		{
			sn = 44;
		}
		else
		if ((sc >= 'a') && (sc <= 'z'))
		{
			sn = (int)(sc - 'a') + 10;
		}
		else
		if ((sc >= 'A') && (sc <= 'Z'))
		{
			sn = (int)(sc - 'A') + 10;
		}
    }

	static void drawChars(int start,int cnt,int x,int y)
	{
		try
		{
    		sx = 0;
    		for (si = 0; si < cnt; si++)
    		{
    			sc = buf[si + start];
    			calcSn();
    			if ((sc != '^')&&(sc != '&')&&(sc != '%'))
    			{
	    			if (sc != ' ')
    				{
	    				g.setClip(sx + x,y,abcw[sn],8);
		    			g.drawImage(img[abc_index],sx + x - abcx[sn],y,20);
			    	}
					sx += abcw[sn];
					if (abcw[sn] > 9) sx--;
				}
	    	}
    	}
    	catch(Exception ex){}
    }
    
    static int getStringWidth(String str)
    {
    	sx = 0;
    	sl = str.length();
    	for (si = 0; si < sl; si++)
    	{
			sc = str.charAt(si);
			calcSn();
   			if ((sc != '^')&&(sc != '&')&&(sc != '*'))
   			{
				sx += abcw[sn];
				if (abcw[sn] > 9) sx--;
			}
    	}
    	return sx;
    }
    //////////////////////////////////////////////////////////////////////////////////
    void addItem(String item)
    {
    	if (vMenu == null) vMenu = new Vector();
    	vMenu.addElement(item.charAt(0) == ' ' ? item.substring(1) : item);
    }

    void addText(String text)
    {
    	w1 = text.length();
    	str = "";
    	str2 = "";
    	sx = j = 0;
    	for (i = 0; i < w1; i++)
    	{
    		sc = text.charAt(i);
    		calcSn();
   			str2 += sc;
			sx += abcw[sn];

			w2 = s_w - 16;
   			if (sx >= w2)
    		{
    			if (str.length() > 0)
    			{
					addItem(str);
					str = "";
				}
				else
				{
					addItem(str2);
					str2 = "";
				}
				sx -= j;
			}

			if ((sc == ' ') || (sc == ',') || (sc == '.') || (sc == '@'))
    		{   	
				str += str2;
				str2 = "";
				j = sx;
    		}
    	}
    	if (str.length() + str2.length() > 0) addItem(str + str2);
    	w1 = 0;
    }

    void addItem(String item,boolean state)
    {
    	addItem(item);
    	vState.addElement(new Boolean(state));
    }

    public void paint(Graphics gr)
    {
		tt = System.currentTimeMillis();
		if (g != gr) g = gr;
		gd = g;
    	try
    	{
			if (state == 101)
			{
				g.setColor(0x000000);
				g.fillRect(0,0,s_w,s_h);
				h1 = s_h >> 1;
   				str = "DEMO ENDED";
   				drawString(str,(s_w - getStringWidth(str)) >> 1,h1 - 16);
   				str = "PLEASE PURCHASE";
   				drawString(str,(s_w - getStringWidth(str)) >> 1,h1);
   				str = "REAL GAME";
   				drawString(str,(s_w - getStringWidth(str)) >> 1,h1 + 16);
			}
			else
    		if (state == 100)
    		{
    			g.setColor(0xFFFFFF);
    			g.fillRect(0,0,s_w,s_h);
    			if (fLogo != null)
    			{
	    			h1 = (s_h - fLogo.fh - 9) >> 1;
    				if ((isLogo2) && (fLogo2 != null))
    				{
		    			h1 = (s_h - fLogo.fh - fLogo2.fh - 9) >> 1;
    					g.setColor(0x0000FF);
	    				g.setClip(0,0,s_w,s_h);
	    				g.drawLine((s_w - fLogo.fw) >> 1,h1 + fLogo.fh + 4,((s_w - fLogo.fw) >> 1) + fLogo.fw,h1 + fLogo.fh + 4);
    					fLogo2.draw((s_w - fLogo2.fw) >> 1,h1 + fLogo.fh + 9);
    				}
    				fLogo.draw((s_w - fLogo.fw) >> 1,h1);
				}
    		}
    		else
    		if (state == 99)
    		{
    			g.setColor(0x000000);
    			g.fillRect(0,0,s_w,s_h);
    			if (fLogo != null) fLogo.draw((s_w - fLogo.fw) >> 1,(s_h - fLogo.fh) >> 1);
    			if (s_h < 100)
    			{
	   				str = "MARV THE";
   					drawString(str,(s_w - getStringWidth(str)) >> 1,(s_h >> 1));
	   				str = "MINER";
   					drawString(str,(s_w - getStringWidth(str)) >> 1,(s_h >> 1) + 16);
   				}
    		}
    		else
    		if (state == 98)
    		{
				g.setColor(0x000000);
				g.fillRect(0,0,s_w,s_h);
				h1 = 48;
   				str = names[c_lvl];
            	if (str == null) str = " ";

           		if ((str.length() + 3) * 8 >= s_w) str = str.substring(0,(s_w / 8) - 5) + "...";

				h1 = (s_h - h1) >> 1;
				drawString(str,(s_w - getStringWidth(str)) >> 1,h1 + 32);
   				str = "LOADING";
   				drawString(str,(s_w - getStringWidth(str)) >> 1,h1);
   				str = "LEVEL " + (c_lvl + 1);
   				drawString(str,(s_w - getStringWidth(str)) >> 1,h1 + 16);
    		}
    		else
    		if (state == 60)
    		{
				g.setColor(0x000000);
				g.fillRect(0,0,s_w,s_h);
				h1 = s_h >> 1;
   				str = "YOUR PLACE";
   				drawString(str,(s_w - getStringWidth(str)) >> 1,h1 - 16);
   				str = "IN SERVER";
   				drawString(str,(s_w - getStringWidth(str)) >> 1,h1);
   				str = "IS " + place;
   				drawString(str,(s_w - getStringWidth(str)) >> 1,h1 + 16);
    		}
    		else

    		if (state == 80)
    		{
				g.setClip(0,0,s_w,s_h);
				g.setColor(0x000000);
				g.fillRect(0,0,s_w,s_h);
				drawString(menuName,(s_w - 84) >> 1,4);
				x = getStringWidth(menuName) + ((s_w - 84) >> 1);

				g.setClip(0,0,s_w,s_h);
				g.setColor(0x604000);
				g.fillRect(x + 12 * menuDisp + 10,2,12,12);

				buf[0] = editText[0];
				if (buf[0] == ' ') buf[0] = '.';
				drawChars(0,1,x + 12, 4);
				buf[0] = editText[1];
				if (buf[0] == ' ') buf[0] = '.';
				drawChars(0,1,x + 24, 4);
				buf[0] = editText[2];
				if (buf[0] == ' ') buf[0] = '.';
				drawChars(0,1,x + 36, 4);

				for (i = 0; i < 4; i++)
					for (j = 0; j < 7; j++)
					{
						buf[0] = letters.charAt(i * 7 + j);
						drawChars(0,1,j * 12 + ((s_w - 84) >> 1), i * 12 + 17);
					}
				g.setClip(0,0,s_w,s_h);
				g.setColor(0xA0B060);
				g.drawRect(editX * 12 + ((s_w - 84) >> 1) - 2, editY * 12 + 14,12,12);

				g.setColor(0x604000);
				g.drawRect(((s_w - 84) >> 1) - 3,13,86,50);

			}
    		else
    		if (state == 70)
    		{
				g.setColor(0x000000);
				g.fillRect(0,0,s_w,s_h);
				x = getStringWidth(menuName);
				drawString(menuName,(s_w - x) >> 1,6);
				if (vMenu != null)
    			if (vMenu.size() > 0)
    			{
		
					y = (menuIndex - menuDisp) * menuHeight + menuTop;

		            h1 = 0;
		            if (vMenu.size() * menuHeight + menuTop + menuTop < s_h)
		            {
		            	h1 = ((s_h - vMenu.size() * menuHeight) >> 1) + 8 - menuTop;
		            }
		            for (j = (w1 == 0 ? 0 : 1) ; j < 2; j++)
					for (i = (j == 0 ? 0 : menuDisp); i < vMenu.size(); i++)
					{
						if (j == 0 || (i - menuDisp < menuRange))
						{
							str = (String)(vMenu.elementAt(i));
							if (i + 1 < vMenu.size() && isState)
							{
								str += ":";
								str += (((Boolean)vState.elementAt(i)).booleanValue()) ? "ON" : "OFF";
							}
							if (j == 0)
							{
								w2 = getStringWidth(str) + (isPointer ? 11 : 0);
								if (w2 > w1) w1 = w2;
							}
							else
							{
								drawString(str,((s_w - 6 - w1) >> 1) + (isPointer ? 13 : 2),(i - menuDisp) * menuHeight + menuTop + h1);
							}
						}
					}
					if (isPointer)
					{
						g.setClip(((s_w - 6 - w1) >> 1) - 2,y + h1,11,8);
						g.drawImage(img[abc_index],((s_w - 6 - w1) >> 1) - 328,y + h1,20);
	   	            }
	   	            if (vMenu.size() > menuRange)
	   	            {
						g.setClip(0,0,s_w,s_h);
						g.setColor(0x6D3114);
						g.fillRect(s_w - 6,menuTop,4,s_h - menuTop - 2);
						g.setColor(0xB2A277);
		
						y1 = (s_h - menuTop - 2) * menuDisp / vMenu.size() + menuTop;
						y2 = (s_h - menuTop - 2) * menuRange / vMenu.size() + 1;
						g.fillRect(s_w - 6,y1,4,y2);
   	
						g.setColor(0x6D3114);
						g.fillRect(s_w - 6,y1,1,1);
						g.fillRect(s_w - 3,y1,1,1);
						g.fillRect(s_w - 6,y1 + y2 - 1,1,1);
						g.fillRect(s_w - 3,y1 + y2 - 1,1,1);

						g.setColor(0x000000);
						g.fillRect(s_w - 6,menuTop,1,1);
						g.fillRect(s_w - 3,menuTop,1,1);
						g.fillRect(s_w - 6,s_h - 3,1,1);
						g.fillRect(s_w - 3,s_h - 3,1,1);
					}
				}
    		}
    		else if (initOK)
    		{
				g.setColor(0x000000);
				if (s_h > a_h) g.fillRect(0,a_h,s_w,s_h - a_h);
				h1 = s_h - a_h;
    			g.drawImage(ioff, - a_x_d, - a_y_d - (h1 > 0 ? h1 : 0),20);


    			if (s_w > a_w)
    			{
    				g.fillRect(0,0, 1 - disp_x_range,s_h);
    				g.fillRect(s_w + disp_x_range - 1,0, 1 - disp_x_range,s_h);
    			}

    			for (i = 0; i < aObj.length; i++)
    			{
 					obj = aObj[i];
	    			if (obj.type == C_M)
   		 			{
	    				frm = fM[obj.subtype];
	    				if (frm != null)
	    				{
	    					x = obj.mx - (frm.fw >> 1) - a_x_d;
				   			y = obj.my - a_y_d;

				   			g.setClip(x,y,frm.fw,frm.fh);
				   			g.drawImage(img[frm.index],x - frm.next(),y,20);
//				   			frm.draw(x - frm.next(),y);
		   		 		}
    				}
	    			if (obj.type == C_Press)
	    			{
	    				x1 = obj.x1 - a_x_d;
	    				y1 = obj.ymin - a_y_d;
	    				y2 = obj.my - a_y_d;

						frm = fPr[(obj.subtype << 1) + 1];
						if (frm != null)
							for (y = obj.ymin, j = y1; y < obj.my; y += frm.h, j += frm.h) 
								frm.draw(x1 - (frm.w >> 1),j,0,y1,a_w,obj.my - obj.ymin - 6);

						frm = fPr[obj.subtype << 1];
						if (frm != null)
							frm.draw(x1 - (frm.w >> 1),y2 - frm.h,0,y1,a_w,obj.my - obj.ymin);
					}
	    			if (obj.type == C_Lift)
	    			{
	    				x1 = obj.x1 - a_x_d;
	    				y1 = obj.ymin - a_y_d;
	    				y2 = obj.my - a_y_d;


						frm = fLi[(obj.subtype << 1) + 1];
						if (frm != null)
							for (y = obj.ymin, j = y1; y < obj.my; y += frm.h, j += frm.h) 
								frm.draw(x1 - (frm.w >> 1),j,0,y1,a_w,obj.my - obj.ymin - obj.fh);

						frm = fLi[obj.subtype << 1];
						if (frm != null)
							frm.draw(x1 - (frm.w >> 1),y2 - frm.h,0,y1,(a_w > s_w) ? a_w : s_w,obj.my - obj.ymin);

	    				g.setClip(0,0,(a_w > s_w) ? a_w : s_w,(a_h > s_h) ? a_h : s_h);
						g.setColor(0x909090);
						g.drawLine(x1 - 2,y1,x1 + 2,y1);
						g.setColor(0x606090);
						g.drawLine(x1 - 1,y1 + 1,x1 + 1,y1 + 1);
					}
    			}

    			for (i = 0; i < dyn.length; i++)
	    			if (dyn[i] != null)
	    			{
	    				if (isBonus && (dyn[i].class_type == Dynamic.T_A) && dyn[i].visible)
	    				{
	    					dBonus.x = dyn[i].x;
	    					dBonus.y = dyn[i].y;
	    					dBonus.draw();
	    				}
	    				else
	    				// blinking pickaxe
	    				if (isBonus && (dyn[i].class_type == Dynamic.T_B) && (dyn[i].type == 2) && (blink == 0))
	    				{
	    				}
	    				else dyn[i].draw();
	    			}


				if (damaged % 2 == 0) man.draw();

        		for (i = 0; i < vM.size(); i++)
        		{
	        		msg = (M)vM.elementAt(i);
    	    		drawString(msg.text, msg.x - a_x_d, msg.y - a_y_d);
        		}
			}
    		if ((fPanel0 != null) && (panel_y > -12) && 
    			((state < 14) || (state == 30) || (state == 31) || (state == 33) || 
    			(state == 34) || (state == 35) || (state == 20) || (state == 40) || (state == 50)))
			{
    			fPanel0.draw(0,panel_y);
    			for (i = fPanel0.fw; i < s_w; i += fPanel1.fw)
    				fPanel1.draw(i,panel_y);
    			fPanel2.draw(s_w - 1,panel_y);

				if (s_w >= 128)
                {
		    		buf[0] = '#';
                	intToString(lifes, 1, 1);
	    			drawChars(0, 2, panel_x + 50, panel_y + 2);
		    		fHead.draw(panel_x + 39,panel_y + 1);
				}

				if ((s_w >= 128) || (lifeDelay == 0))
				{
		    		intToString(scores, 0, 5);
		    		drawChars(0, 5, panel_width + panel_x - 43, panel_y + 2);
		    	}
		    	else
		    	{
		    		fHead.draw(panel_width - 35,panel_y + 1);
		    		buf[0] = '#';
                	intToString(lifes, 1, 1);
	    			drawChars(0, 2, panel_width - 22, panel_y + 2);
		    	}

		    	if (dumpTime > 0 && midlet.cheats)
		    	{
	               	intToString(memorySize, 0, 8);
		    		drawChars(0, 8, 6, 16);
		    		dumpTime--;
				}

				intToString((int)currentTime,0,3);
	    		drawChars(0, 3, panel_x + 12, panel_y + 2);

    			g.setClip(0,panel_y,s_w,s_h);
	    		if ((start_closed_blocks > 0) && (state == 0))
    			{
        			g.setColor(0x00a0a0);
        			g.drawLine(panel_x,panel_y + panel_height - 1,panel_x + panel_width * (start_closed_blocks - closed_blocks) / start_closed_blocks,panel_y + panel_height - 1);
        		}

			}
            /*
			if (state == 0)
			{
        		g.setColor(0xFFFFFF);
				tt2 = System.currentTimeMillis() - tt;
				tsum += tt2;
//			    	g.drawString(Long.toString(tt2),10,20,20);
//			    	if (tcnt > 0) g.drawString(Long.toString(tsum / tcnt),10,40,20);
				if (tcnt++ > 200) tsum = tcnt = 0;
			}
            */
			if ((state == 14) || (state == 15) || (state == 20))
			{
   				g.setClip(0,0,s_w,s_h);
    			g.setColor(0x000000);
   				g.fillRect(0,a_h - a_y_d,s_w,s_h);
   			}
			if (state == 15)
			{
				for (i = 0; i < 10; i++)
   				{
   					x = rnd(s_w);
   					y = rnd(s_h);
   					g.setColor(0x404040 + rnd(0x404040));
					g.drawLine(x,y,x,y);
    			}
   			}
			if ((state == 14) || (state == 15))
			{
				str = "THE END";
				drawString(str,(s_w - getStringWidth(str))>> 1,((s_h - 8) >> 1) + a_h - a_y_d);
			}
			if (state == 50)
			{
				str = "GAME OVER";
				w1 = getStringWidth(str);
				g.setColor(0x000000);
				g.setClip(0,0,s_w,s_h);
				g.fillRect(((s_w - w1) >> 1) - 10,(s_h >> 1) - 10, w1 + 20, 20);
				g.setColor(0xB2A277);
				g.drawRect(((s_w - w1) >> 1) - 10,(s_h >> 1) - 10, w1 + 20, 20);

				drawString(str,(s_w - w1)>> 1,(s_h >> 1) - 4);
			}
			if (fire != null) fire.draw();
		}
		catch(Exception ex)
		{
		}
    }

	int its_x,its_i,its_n;
    void intToString(int n,int disp,int digits)
    {
    	for (its_x = n, its_i = digits - 1; its_i >= 0; its_i --, its_x /= 10)
    		buf[disp + its_i] = (char)(its_x % 10 + '0');
    }

    Thread t = null;
    long tstart = 0,tcur = 0;

    int blink,blinkDelay;
	public void run()
	{
        t = Thread.currentThread();
       	if (mainThread != null); // dummy code 
		while (t == mainThread)
		{
			try
			{
				t.sleep(10);
			}
			catch(Exception iex){}
			tcur = System.currentTimeMillis();

			t.yield();
			if (vibra_delay > 0)
			{
				if (--vibra_delay <= 0)
				{

    				if (vendor == 3)
    				try
		    		{
		//    			Class.forName("com.vodafone.v10.system.device.DeviceControl");
						com.vodafone.v10.system.device.DeviceControl.getDefaultDeviceControl().setDeviceActive(com.vodafone.v10.system.device.DeviceControl.VIBRATION,false);
						vibra_delay = 0;
		    		}
		    		catch(Exception ex){}
				}
			}
			if ((tcur - tstart > 50) && running)
			{
				tstart = tcur;
				tcur = System.currentTimeMillis() - bonusTime;
				if (isBonus)
				if (tcur > 8000)
				{
					// switch off bonus mode
					isBonus = false;
					for (i = 0; i < dyn.length; i++)
						if (dyn[i] != null)
							if ((dyn[i].class_type == Dynamic.T_B) && (dyn[i].type == 2) && dyn[i].inUse)
							{
								dyn[i].restart();
								dyn[i].visible = false;
								man.inUse = false;
							}
				}
				else
				{
					blinkDelay = 8 - (int)(tcur / 1000);
					blink--;
					if (blink < 0) blink = blinkDelay;
				}

                try
                {
   					if (damaged > 0) damaged--;
   					if (lifeDelay > 0) lifeDelay--;
    				switch(state)
    				{
    				case 101:
    					LOGO_TIME --;
    					if ((LOGO_TIME <= 0) || (action != -15)) 
    					{
							midlet.isFirst = 1;
							midlet.menuLevel = 0;
							midlet.paused = false;
							midlet.storeScores();
    					}
    					break;
    				case 100:
    					LOGO_TIME -= 50;
    					if ((LOGO_TIME <= 0) || (action != -15)) 
    					{
    						action = -15;
    						fLogo = null;
    						fLogo2 = null;
    						state = 99;
    						init();
    					}
    					break;
    				case 99:
    					LOGO_TIME -= 50;
    					if ((LOGO_TIME <= 0) || (action != -15)) 
    					{
    						action = -15;
    						fLogo = null;
    						initOK = false;
    						midlet.startMenu();
    					}
    					break;
    				case 98:
    					LOGO_TIME --;
    					if ((LOGO_TIME <= 0) || (action != -15)) 
    					{
    						state = 0;
    						init();
    					}
    					break;
    				case 70:
    					updateMenu();
    					break;
    				case 80:
    					updateEditor();
    					break;
    				case 60:
    					LOGO_TIME -= 50;
    					if ((LOGO_TIME <= 0) || (action != -15)) 
    					{
    						midlet.menuLevel = 2;
    						midlet.returnMenu();
    						action = -15;
    					}
    					break;
    				case 0:
    					update();

            			if ((!isKeyPressed) && (action != -15))
            			{
            				action = -15;
 	         				man.stop();
            			}
    			   		currentTime = levelTime - (int)((System.currentTimeMillis() - startTime) / 1000);
    			   		if (currentTime <= 0)
    			   		{
    			   			lifes = 0;
    			   			state = 3;
    			   		}
		    			if (closed_blocks <= 0)
		    			{
							addMessage(man.x,man.y,"100");
							scores += 100;
		    				state = 1;
		    			}
    					break;
    				case 1:
    					updateMsg();
    					scores += 10;
    					currentTime -= 10;
    					if (currentTime < 0)
    					{
    						currentTime = 0;
    						state = 2;
    					}
    					break;
    				case 2:
    					if (nextLevel != null)
    					{
	    	           		man.a2 = 0;
    	    	           	state = 20;
    	            	}
    	            	else state = 14;
    					break;
    	           	case 3:
    	           		beep(1);
    	           		lifeDelay = 20;
    	           		lifes--;
    					man.visible = false;
    					fire.visible = true;
    					fire.a2 = 1;
    					fire.x = man.x;
    					fire.y = man.y;
    					fire.finished = false;
    					delay = 25;
    					state = 5;
    					break;
    				case 5:
    					update();
    					if (fire.finished) fire.visible = false;
    					if (--delay <= 0)
    					{
        					fire.visible = false;
    						state = 40;
    					}
    					break;
    				case 14:
    					a_y_d += 2;
    					if (a_y_d > a_h)
    					{
    						state = 15;
    						delay = 100;
    						fire.finished = true;
    					}
    					break;
    				case 15:
    					if (fire.finished)
    					{
    						fire.x = rnd(s_w - 40) + a_x_d + 20;
    						fire.y = rnd(s_h - 40) + a_y_d + 20;
    						fire.finished = false;
    						fire.visible = true;
    					}
    					if ((--delay <= 0) || (isKeyPressed))
    					{
    						fire.visible = false;
    						state = 51;
    					}
    					break;
    				case 20:
    					updateMsg();
    					a_y_d += 2;
    					panel_y--;
    					if (a_y_d > a_h)
    					{
    						if (midlet.demoLevels <= (c_lvl + 1) && midlet.isDemo)
    						{ 
    							release();
    							state = 101;
    							init();
    						}
    						else // loading next level
    						{
	    						if (midlet.demoLevels <= ++c_lvl && midlet.isDemo)
	    						{
	    						}
	    						else midlet.storeLevel(c_lvl);
    							release();
    							state = 98;
    							init();
							}
    					}
    					break;
    				case 30:
    					update();
    					man.cb();
    					if (man.finished)
    					{
        					delay = 20;
	    	           		lifeDelay = 20;
	    					lifes --;
        					state = 31;
    					}
    					break;
    				case 31:
    					update();
    					man.cb();
    					if (--delay <= 0) state = 40;
    					break;
    				case 33:
    					update();
    					man.cb();
    					if (man.finished)
    					{
    						man.curObj = man.curObj.nextObj;
    						man.x = man.new_x = man.curObj.x1;
    						man.y = man.new_y = man.min_y = man.curObj.y1 - 1;
    						man.finished = false;
    						man.visible = false;
    						state = 34;
    					}
    					break;
    				case 34:
    					update();
    					man.cb();

				      	t_x_d = man.x - (s_w >> 1);
			    	  	t_y_d = man.y - (s_h >> 1);
				    	if (t_x_d < 0) t_x_d = 0;
				    	if (t_y_d < 0) t_y_d = 0;
				    	if (t_x_d >= disp_x_range) t_x_d = disp_x_range;
				    	if (t_y_d >= disp_y_range) t_y_d = disp_y_range;

				    	if (t_x_d < a_x_d) a_x_d --;
				    	if (t_x_d > a_x_d) a_x_d ++;
				    	if (t_y_d < a_y_d) a_y_d --;
				    	if (t_y_d > a_y_d) a_y_d ++;

				    	if ((t_x_d - 2 <= a_x_d) && (t_x_d + 2 >= a_x_d) && (t_y_d - 2 <= a_y_d) && (t_y_d + 2 >= a_y_d))
				    	{
				    		a_x_d = t_x_d;
				    		a_y_d = t_y_d;
    						man.a1 = 15;
    						man.visible = true;
				    		state = 35;
				    	}
				    	else
				    	{
				    		x = t_x_d - a_x_d;
				    		y = t_y_d - a_y_d;
				    		if (abs(x) > abs(y))
				    		{
				    			y = 2 * y / x;
				    			x = x > 0 ? 2 : -2;
				    		}
				    		else
				    		{
				    			x = 2 * x / y;
				    			y = y > 0 ? 2 : -2;
				    		}
				    		a_x_d += x;
				    		a_y_d += y;
				    	}
				    	break;

    				case 35:
    					update();
    					man.cb();
    					if (man.finished)
    					{
    						state = 0;
    						man.isFalling = true;
    						man.curObj = null;
    					}
    					break;
    				case 40:
						if (lifes > 0)
						{
							for (i = 0; i < dyn.length; i++)
								if (dyn[i] != null)
								if ((dyn[i].class_type != Dynamic.T_B) || (dyn[i].type == 1) || (dyn[i].type == 2))
								{
									dyn[i].restart();
									dyn[i].visible = true;
								}
	                    	man.restart();
							man.visible = true;
							isBonus = false;
							damaged = 40;
                        	locateMan();
	    	           		lifeDelay = 20;
                        	state = 0;
						}
						else
						{
							delay = 30;
							state = 50;
						}
						break;
					case 50:
						if (panel_y >= -12) panel_y --;
						if ((-- delay < 0) || isKeyPressed)
						{
							state = 51;
						}
						break;
					case 51:
						action = -15;
						initOK = false;
						ld = false;
						midlet.isFirst = 1;
						midlet.menuLevel = 0;
						midlet.paused = false;
						midlet.storeScores();
						break;
    				}
                }
                catch (Exception e)
                {
                	e.printStackTrace();
                }
    			repaint();
				serviceRepaints();
        	}
		}
	}
	int abs(int x)
	{
		return (x >= 0) ? x : -x;
	}

    synchronized public void start() 
    {
        if (mainThread == null) 
        {
            mainThread = new Thread(this);
            mainThread.start();
        }
    }
    
    synchronized public void stop() 
    {
        mainThread = null;
    }

    static String gp(String name)
    {
    	if (hp == null)
    	{
    	    hp = new Hashtable();
            try
            {
	    	    in2 = new DataInputStream(midlet.getClass().getResourceAsStream("/Res/m.c"));
    			char c;
    			int i,mode = 0;
    			String key = "",value = "";
    			while((i = in2.read()) != -1)
    			{
    				c = (char)i;
    				if (c == '\n')
    				{
    					mode = 0;
    					if ((key.length() > 0) && (value.length() > 0))
    						hp.put(key.trim().toLowerCase(),value.trim().toLowerCase());
    					key = value = "";
    				}
    				if (mode == 2) continue;
    				if (c == '#')
    				{
    					mode = 2;
    					continue;
    				}
    				if (c == '=')
    				{
    					mode = 1;
    					continue;
    				}
    				if (mode == 0) key += c;
    				if (mode == 1) value += c;
    			}
    			in2.close();
    		}
    		catch(Exception e)
    		{
    			out("gp: " + e);
			}
    		in2 = null;
    		System.gc();
    	}
		return (String)hp.get(name);
    }

    ////////////////////////////////////////////////////////
    
	// PAK file stream
	DataInputStream pk_in = null;

	// header fields
	static int numFTEntries = 0;
	static byte cipherAddition = 0;
	static byte cipherValue = 0;
	//

	// file table fields
	static byte[] filename = null;
	static int pk_offset[];
	static int pk_size[];
	static int pk_index[];
	static String sFileName = null;

	static byte[] buffer = null;
	//

	static int skipped = 0;		// count of skipped bytes when reading header and file table

	static int pk_i,pk_j,pk_n,pk_v;
	static boolean noZero;

	// internal function which reads one coded byte and decodes it
	byte readCByte() throws IOException
	{
		int b = pk_in.read();
		b = (cipherAddition == 1 ? ((b - cipherValue) & (0xFF)) : ((b + cipherValue) & 0xFF));
		return (byte)b;
	}

	private int readCInt() throws IOException
	{
		pk_v = (byte)readCByte() & 0x00FF;
		pk_v |= ((byte)readCByte() & 0x00FF) << 8;
		pk_v |= ((byte)readCByte() & 0x00FF) << 16;
		pk_v |= ((byte)readCByte() & 0x00FF) << 24;
		return pk_v;
	}

	private int readCBytes(byte[]b, int l) throws IOException
	{
		pk_n = 0;
		noZero = true;
		for (pk_j = 0; pk_j < l; pk_j++)
		{
			b[pk_j] = readCByte();
			if (b[pk_j] != 0)
			{
				if (noZero) pk_n++;
			}
			else noZero = false;
		}
		return pk_n;
	}

	int _readInt() throws Exception
	{
		pk_v = (byte)pk_in.read() & 0x000000FF;
		pk_v |= ((byte)pk_in.read() & 0x000000FF) << 8;
		pk_v |= ((byte)pk_in.read() & 0x000000FF) << 16;
		pk_v |= ((byte)pk_in.read() & 0x000000FF) << 24;
		return pk_v;
	}

	public void loadImages()
	{
		// reading the header	
		try
		{
			pk_in = new DataInputStream(midlet.getClass().getResourceAsStream("/Res/pak0.map"));
			pk_in.read(filename,0,6);
			if (!(new String(filename,0,6).equals("DEEPAK"))) return;
			_readInt();
			numFTEntries = _readInt();

			cipherAddition = (byte)pk_in.read();
			cipherValue = (byte)pk_in.read();
			pk_in.read(filename,0,10);
			_readInt();
			skipped += 30;

			if (numFTEntries > img.length) numFTEntries = img.length;

			// search for entry name

			// reading file table
			for (pk_i = 0; pk_i < numFTEntries; pk_i++, skipped += 22)
			{
				pk_n = readCBytes(filename,filename.length);
				pk_size[pk_i] = readCInt();
				pk_offset[pk_i] = readCInt();
				pk_index[pk_i] = -1;
				readCInt();

				sFileName = new String(filename,0,pk_n).toLowerCase();
				for (pk_j = 0; pk_j < img_names.length; pk_j++)
				{
					if (img_names[pk_j] != null) 
					{
						if (img_names[pk_j].equals(sFileName))
						{
							pk_index[pk_i] = pk_j;
//							System.out.println("Enqueued " + img_names[pk_j]);
							img_names[pk_j] = null;
							break;
						}
					}
				}
			}
			sFileName = null;

			buffer = new byte[7120];
			// reading images
			for (pk_i = 0; pk_i < numFTEntries; pk_i++)
			{
				if (pk_index[pk_i] != -1)
				{
					readCBytes(buffer,pk_size[pk_i]);
					img[pk_index[pk_i]] = Image.createImage(buffer,0,pk_size[pk_i]);
				}
				else pk_in.skip(pk_size[pk_i]);
				skipped += pk_size[pk_i];
			}
			pk_in.close();
			pk_in = null;
			buffer = null;
			System.gc();
		}
		catch(Exception ex){}
	}
}
